using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EntLibExtensions;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using System.Data.SqlClient;

namespace EntLibExtensions.Tests
{
    /// <summary>
    /// Summary description for SqlExceptionWrapHandlerFixture
    /// </summary>
    [TestClass]
    public class SqlExceptionWrapHandlerFixture
    {
        private const string policyName = "Exception Policy";
        private const string policyName2 = "Exception Policy 2";


        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void CallPolicyWithConfiguredCode()
        {
            SqlException ex = SqlExceptionCreator.CreateSqlException("SqlException", new Error(2601, "Original SQL 2601"));
            try
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, policyName);
            }
            catch (Exception returnedException)
            {
                Assert.AreEqual(returnedException.GetType(), typeof(ArgumentException));
                Assert.AreEqual(returnedException.Message, "This is the message for code 2601");
                Assert.AreEqual(returnedException.InnerException.GetType(), typeof(SqlException));
                Assert.AreEqual(returnedException.InnerException.Message, ex.Message);
            }
        }

        [TestMethod]
        public void CallPolicyWithConfiguredCodeInSecondError()
        {
            SqlException ex = SqlExceptionCreator.CreateSqlException("SqlException", 
                new Error(123, "Original SQL 123"),
                new Error(547, "Original SQL 547"));
            try
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, policyName);
            }
            catch (Exception returnedException)
            {
                Assert.AreEqual(returnedException.GetType(), typeof(InvalidOperationException));
                Assert.AreEqual(returnedException.Message, "This is the message for code 547");
                Assert.AreEqual(returnedException.InnerException.GetType(), typeof(SqlException));
                Assert.AreEqual(returnedException.InnerException.Message, ex.Message);
            }
        }

        [TestMethod]
        public void CallPolicyWithNonConfiguredCodeAndDefaultException()
        {
            SqlException ex = SqlExceptionCreator.CreateSqlException("SqlException", new Error(123, "Original SQL 123"));
            try
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, policyName);
            }
            catch (Exception returnedException)
            {
                Assert.AreEqual(returnedException.GetType(), typeof(ApplicationException));
                Assert.AreEqual(returnedException.Message, "This is the default exception message");
                Assert.AreEqual(returnedException.InnerException.GetType(), typeof(SqlException));
                Assert.AreEqual(returnedException.InnerException.Message, ex.Message);
            }
        }

        [TestMethod]
        public void CallPolicyWithNonConfiguredCodeWithoutDefaultException()
        {
            SqlException ex = SqlExceptionCreator.CreateSqlException("SqlException", new Error(123, "Original SQL 123"));
            try
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, policyName2);
            }
            catch (Exception returnedException)
            {
                Assert.AreEqual(returnedException, ex);
            }
        }

        [TestMethod]
        public void CallPolicyWithWrongExceptionType()
        {
            ApplicationException ex = new ApplicationException();
            try
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, policyName);
            }
            catch (Exception returnedException)
            {
                Assert.AreEqual(returnedException.GetType(), typeof(ExceptionHandlingException));
                Assert.IsNull(returnedException.InnerException);

            }

        }


  
    }
}
